#!/usr/bin/python

#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.
#       

import board, pygame, sys, os
from engines import *

pygame.init()
scr_size = 550, 630
bordercolour = 255, 200, 0

screen = pygame.display.set_mode(scr_size)
pygame.display.set_caption("4D TicTacToe")

paper = pygame.image.load("paper_v1.png")
X = pygame.image.load("X.png").convert()
O = pygame.image.load("O.png").convert()
colours = {1: X, -1: O}

pygame.font.init()
standardfont = pygame.font.Font('freesansbold.ttf', 20)

pap_size = paper.get_size()
borderwidth = (scr_size[0]-pap_size[0])/2
pap_left = (scr_size[0]-pap_size[0])/2
pap_up = borderwidth
square_size = 47
in_between_size = 48
field_size = 3*square_size + in_between_size
fln = 15 # first line
lines = [fln + (k+board.size*l) * square_size + l * in_between_size \
        for l in range(board.size)
        for k in range(board.size+1)]
screen.fill(bordercolour)
screen.blit(paper, (pap_left, pap_up))

pos = board.Position()

def draw(coord, colour):
    """Draw an X or O at coord
    """
    adj = 6
    paper_location = coord[2]*field_size + coord[3]*square_size, \
                     coord[0]*field_size + coord[1]*square_size
    location = pap_left + adj + paper_location[0], \
               pap_up + adj + paper_location[1]
    screen.blit(colours[colour], location)

def draw_position(pos):
    """Draw the whole position
    """
    screen.fill(bordercolour)
    screen.blit(paper, (pap_left, pap_up))
    for coord in board.coord_list:
        colour = pos.check(coord)
        if not colour == 0:
            draw(coord, colour)
    score_display_distance = scr_size[0] / 3
    score_xcoords = (scr_size[0] - score_display_distance)/2, (scr_size[0] + score_display_distance)/2
    screen.blit(X, (score_xcoords[0], pap_up + pap_size[1] + borderwidth))
    screen.blit(O, (score_xcoords[1], pap_up + pap_size[1] + borderwidth))
    score_X = standardfont.render(str(pos.count_rows(1)), 1, (0,0,0))
    score_O = standardfont.render(str(pos.count_rows(-1)), 1, (0,0,0))
    screen.blit(score_X, (score_xcoords[0], pap_up + pap_size[1] + borderwidth + square_size))
    screen.blit(score_O, (score_xcoords[1], pap_up + pap_size[1] + borderwidth + square_size))
    pygame.display.flip()

def move():
    coord = [-1,-1,-1,-1]
    click_at = pygame.mouse.get_pos()
    if lines[0] < click_at[0] < lines[1]:
        coord[2], coord[3] = 0, 0
    elif lines[1] < click_at[0] < lines[2]:
        coord[2], coord[3] = 0, 1
    elif lines[2] < click_at[0] < lines[3]:
        coord[2], coord[3] = 0, 2
    elif lines[4] < click_at[0] < lines[5]:
        coord[2], coord[3] = 1, 0
    elif lines[5] < click_at[0] < lines[6]:
        coord[2], coord[3] = 1, 1
    elif lines[6] < click_at[0] < lines[7]:
        coord[2], coord[3] = 1, 2
    elif lines[8] < click_at[0] < lines[9]:
        coord[2], coord[3] = 2, 0
    elif lines[9] < click_at[0] < lines[10]:
        coord[2], coord[3] = 2, 1
    elif lines[10] < click_at[0] < lines[11]:
        coord[2], coord[3] = 2, 2
    else:
        raise board.IllegalMove("No Hit.")

    if lines[0] < click_at[1] < lines[1]:
        coord[0], coord[1] = 0, 0
    elif lines[1] < click_at[1] < lines[2]:
        coord[0], coord[1] = 0, 1
    elif lines[2] < click_at[1] < lines[3]:
        coord[0], coord[1] = 0, 2
    elif lines[4] < click_at[1] < lines[5]:
        coord[0], coord[1] = 1, 0
    elif lines[5] < click_at[1] < lines[6]:
        coord[0], coord[1] = 1, 1
    elif lines[6] < click_at[1] < lines[7]:
        coord[0], coord[1] = 1, 2
    elif lines[8] < click_at[1] < lines[9]:
        coord[0], coord[1] = 2, 0
    elif lines[9] < click_at[1] < lines[10]:
        coord[0], coord[1] = 2, 1
    elif lines[10] < click_at[1] < lines[11]:
        coord[0], coord[1] = 2, 2
    else:
        raise board.IllegalMove("No Hit.")

    num = board.convert(coord)
    pos.move(num)

def finished(message):
    pygame.display.init()
    screen = pygame.display.set_mode((460, 120))
    pygame.display.set_caption('Game is finished')
    foreg = 0, 0, 0
    screen.fill(bordercolour)
    pos = [20, 20]
    for text in message.split('\n'):
        msg = standardfont.render(text, 1, foreg)
        screen.blit(msg, pos)
        pos[1] += standardfont.get_height()

    pygame.display.flip()
    endkeys = pygame.K_ESCAPE, pygame.K_SPACE, pygame.K_RETURN
    while True:
        for e in pygame.event.get():
            if e.type == pygame.QUIT or \
                   (e.type == pygame.KEYDOWN and e.key in endkeys):
                sys.exit()



draw_position(pos)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: 
            sys.exit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            try:
                move()
                #computer_1_move(pos)
            except board.IllegalMove as why:
                print "Illegal Move!", why
                continue
            else:
                draw_position(pos)
            try:
                #hand-optimized parameters
                computer_2_move(pos, a = 0.48, b = 0.7, c = 0.248, d = 0.28)
                #computer_1_move(pos)
            except board.IllegalMove as why:
                print "Board Full..."
                result = pos.count_rows(1) - pos.count_rows(-1)
                if result > 0:
                    finished("I haven't slept very well last night.\n"
                           "You have won by a margin of {0} rows.".format(result))
                elif result < 0:
                    finished("Please try to play a bit better.\n"
                           "I have won by a margin of {0} rows.".format(-result))
                else:
                    finished("Wow! Draw....")
            draw_position(pos)
            print pos.count_rows(1) , "rows for X"
            print pos.count_rows(-1), "rows for O"
            print "___________________________"
